package com.google.typography.font.sfntly.table.opentype.testing;

import com.google.typography.font.sfntly.Font;
import com.google.typography.font.sfntly.Tag;
import com.google.typography.font.sfntly.table.opentype.GSubTable;
import com.google.typography.font.sfntly.table.opentype.ScriptListTable;
import com.google.typography.font.sfntly.table.opentype.ScriptTag;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

class FontLanguages {
  private static final String[][] langScriptData = {
    {"aa", "Latn"},
    {"ab", "Cyrl"},
    {"abq", "Cyrl"},
    {"ace", "Latn"},
    {"ach", "Latn"},
    {"ada", "Latn"},
    {"ady", "Cyrl"},
    {"ae", "Avst"},
    {"af", "Latn"},
    {"agq", "Latn"},
    {"aii", "Cyrl"},
    {"aii", "Syrc"},
    {"ain", "Kana", "Latn"},
    {"ak", "Latn"},
    {"akk", "Xsux"},
    {"ale", "Latn"},
    {"alt", "Cyrl"},
    {"am", "Ethi"},
    {"amo", "Latn"},
    {"an", "Latn"},
    {"anp", "Deva"},
    {"ar", "Arab"},
    {"ar", "Syrc"},
    {"arc", "Armi"},
    {"arn", "Latn"},
    {"arp", "Latn"},
    {"arw", "Latn"},
    {"as", "Beng"},
    {"asa", "Latn"},
    {"ast", "Latn"},
    {"av", "Cyrl"},
    {"awa", "Deva"},
    {"ay", "Latn"},
    {"az", "Arab", "Cyrl", "Latn"},
    {"ba", "Cyrl"},
    {"bal", "Arab", "Latn"},
    {"ban", "Latn"},
    {"ban", "Bali"},
    {"bas", "Latn"},
    {"bax", "Bamu"},
    {"bbc", "Latn"},
    {"bbc", "Batk"},
    {"be", "Cyrl"},
    {"bej", "Arab"},
    {"bem", "Latn"},
    {"bez", "Latn"},
    {"bfq", "Taml"},
    {"bft", "Arab"},
    {"bft", "Tibt"},
    {"bfy", "Deva"},
    {"bg", "Cyrl"},
    {"bh", "Deva", "Kthi"},
    {"bhb", "Deva"},
    {"bho", "Deva"},
    {"bi", "Latn"},
    {"bik", "Latn"},
    {"bin", "Latn"},
    {"bjj", "Deva"},
    {"bku", "Latn"},
    {"bku", "Buhd"},
    {"bla", "Latn"},
    {"blt", "Tavt"},
    {"bm", "Latn"},
    {"bn", "Beng"},
    {"bo", "Tibt"},
    {"bqv", "Latn"},
    {"br", "Latn"},
    {"bra", "Deva"},
    {"brx", "Deva"},
    {"bs", "Latn"},
    {"btv", "Deva"},
    {"bua", "Cyrl"},
    {"buc", "Latn"},
    {"bug", "Latn"},
    {"bug", "Bugi"},
    {"bya", "Latn"},
    {"byn", "Ethi"},
    {"ca", "Latn"},
    {"cad", "Latn"},
    {"car", "Latn"},
    {"cay", "Latn"},
    {"cch", "Latn"},
    {"ccp", "Beng"},
    {"ccp", "Cakm"},
    {"ce", "Cyrl"},
    {"ceb", "Latn"},
    {"cgg", "Latn"},
    {"ch", "Latn"},
    {"chk", "Latn"},
    {"chm", "Cyrl", "Latn"},
    {"chn", "Latn"},
    {"cho", "Latn"},
    {"chp", "Latn"},
    {"chp", "Cans"},
    {"chr", "Cher", "Latn"},
    {"chy", "Latn"},
    {"cja", "Arab"},
    {"cja", "Cham"},
    {"cjm", "Cham"},
    {"cjm", "Arab"},
    {"cjs", "Cyrl"},
    {"ckb", "Arab"},
    {"ckt", "Cyrl"},
    {"co", "Latn"},
    {"cop", "Arab", "Copt", "Grek"},
    {"cpe", "Latn"},
    {"cr", "Cans", "Latn"},
    {"crh", "Cyrl"},
    {"crk", "Cans"},
    {"cs", "Latn"},
    {"csb", "Latn"},
    {"cu", "Glag"},
    {"cv", "Cyrl"},
    {"cy", "Latn"},
    {"da", "Latn"},
    {"dak", "Latn"},
    {"dar", "Cyrl"},
    {"dav", "Latn"},
    {"de", "Latn"},
    {"de", "Runr"},
    {"del", "Latn"},
    {"den", "Latn"},
    {"den", "Cans"},
    {"dgr", "Latn"},
    {"din", "Latn"},
    {"dje", "Latn"},
    {"dng", "Cyrl"},
    {"doi", "Arab"},
    {"dsb", "Latn"},
    {"dua", "Latn"},
    {"dv", "Thaa"},
    {"dyo", "Arab"},
    {"dyo", "Latn"},
    {"dyu", "Latn"},
    {"dz", "Tibt"},
    {"ebu", "Latn"},
    {"ee", "Latn"},
    {"efi", "Latn"},
    {"egy", "Egyp"},
    {"eka", "Latn"},
    {"eky", "Kali"},
    {"el", "Grek"},
    {"en", "Latn"},
    {"en", "Dsrt", "Shaw"},
    {"eo", "Latn"},
    {"es", "Latn"},
    {"et", "Latn"},
    {"ett", "Ital", "Latn"},
    {"eu", "Latn"},
    {"evn", "Cyrl"},
    {"ewo", "Latn"},
    {"fa", "Arab"},
    {"fan", "Latn"},
    {"ff", "Latn"},
    {"fi", "Latn"},
    {"fil", "Latn"},
    {"fil", "Tglg"},
    {"fiu", "Latn"},
    {"fj", "Latn"},
    {"fo", "Latn"},
    {"fon", "Latn"},
    {"fr", "Latn"},
    {"frr", "Latn"},
    {"frs", "Latn"},
    {"fur", "Latn"},
    {"fy", "Latn"},
    {"ga", "Latn"},
    {"gaa", "Latn"},
    {"gag", "Latn"},
    {"gag", "Cyrl"},
    {"gay", "Latn"},
    {"gba", "Arab"},
    {"gbm", "Deva"},
    {"gcr", "Latn"},
    {"gd", "Latn"},
    {"gez", "Ethi"},
    {"gil", "Latn"},
    {"gl", "Latn"},
    {"gld", "Cyrl"},
    {"gn", "Latn"},
    {"gon", "Deva", "Telu"},
    {"gor", "Latn"},
    {"got", "Goth"},
    {"grb", "Latn"},
    {"grc", "Cprt", "Grek", "Linb"},
    {"grt", "Beng"},
    {"gsw", "Latn"},
    {"gu", "Gujr"},
    {"guz", "Latn"},
    {"gv", "Latn"},
    {"gwi", "Latn"},
    {"ha", "Arab", "Latn"},
    {"hai", "Latn"},
    {"haw", "Latn"},
    {"he", "Hebr"},
    {"hi", "Deva"},
    {"hil", "Latn"},
    {"hit", "Xsux"},
    {"hmn", "Latn"},
    {"hne", "Deva"},
    {"hnn", "Latn"},
    {"hnn", "Hano"},
    {"ho", "Latn"},
    {"hoc", "Deva"},
    {"hoj", "Deva"},
    {"hop", "Latn"},
    {"hr", "Latn"},
    {"hsb", "Latn"},
    {"ht", "Latn"},
    {"hu", "Latn"},
    {"hup", "Latn"},
    {"hy", "Armn"},
    {"hz", "Latn"},
    {"ia", "Latn"},
    {"iba", "Latn"},
    {"ibb", "Latn"},
    {"id", "Latn"},
    {"id", "Arab"},
    {"ig", "Latn"},
    {"ii", "Yiii"},
    {"ii", "Latn"},
    {"ik", "Latn"},
    {"ilo", "Latn"},
    {"inh", "Cyrl"},
    {"inh", "Arab", "Latn"},
    {"is", "Latn"},
    {"it", "Latn"},
    {"iu", "Cans"},
    {"iu", "Latn"},
    {"ja", "Jpan"},
    {"jmc", "Latn"},
    {"jpr", "Hebr"},
    {"jrb", "Hebr"},
    {"jv", "Latn"},
    {"jv", "Java"},
    {"ka", "Geor"},
    {"kaa", "Cyrl"},
    {"kab", "Latn"},
    {"kac", "Latn"},
    {"kaj", "Latn"},
    {"kam", "Latn"},
    {"kbd", "Cyrl"},
    {"kca", "Cyrl"},
    {"kcg", "Latn"},
    {"kde", "Latn"},
    {"kdt", "Thai"},
    {"kea", "Latn"},
    {"kfo", "Latn"},
    {"kfr", "Deva"},
    {"kg", "Latn"},
    {"kha", "Latn"},
    {"kha", "Beng"},
    {"khb", "Talu"},
    {"khq", "Latn"},
    {"kht", "Mymr"},
    {"ki", "Latn"},
    {"kj", "Latn"},
    {"kjh", "Cyrl"},
    {"kk", "Cyrl"},
    {"kk", "Arab"},
    {"kl", "Latn"},
    {"kln", "Latn"},
    {"km", "Khmr"},
    {"kmb", "Latn"},
    {"kn", "Knda"},
    {"ko", "Hang", "Kore"},
    {"koi", "Cyrl"},
    {"kok", "Deva"},
    {"kos", "Latn"},
    {"kpe", "Latn"},
    {"kpy", "Cyrl"},
    {"kr", "Latn"},
    {"krc", "Cyrl"},
    {"kri", "Latn"},
    {"krl", "Cyrl", "Latn"},
    {"kru", "Deva"},
    {"ks", "Arab", "Deva"},
    {"ksb", "Latn"},
    {"ksf", "Latn"},
    {"ksh", "Latn"},
    {"ku", "Arab", "Cyrl", "Latn"},
    {"kum", "Cyrl"},
    {"kut", "Latn"},
    {"kv", "Cyrl", "Latn"},
    {"kw", "Latn"},
    {"ky", "Arab", "Cyrl"},
    {"ky", "Latn"},
    {"kyu", "Kali"},
    {"la", "Latn"},
    {"lad", "Hebr"},
    {"lag", "Latn"},
    {"lah", "Arab"},
    {"lam", "Latn"},
    {"lb", "Latn"},
    {"lbe", "Cyrl"},
    {"lcp", "Thai"},
    {"lep", "Lepc"},
    {"lez", "Cyrl"},
    {"lg", "Latn"},
    {"li", "Latn"},
    {"lif", "Deva", "Limb"},
    {"lis", "Lisu"},
    {"lki", "Arab"},
    {"lmn", "Telu"},
    {"ln", "Latn"},
    {"lo", "Laoo"},
    {"lol", "Latn"},
    {"loz", "Latn"},
    {"lt", "Latn"},
    {"lu", "Latn"},
    {"lua", "Latn"},
    {"lui", "Latn"},
    {"lun", "Latn"},
    {"luo", "Latn"},
    {"lus", "Beng"},
    {"lut", "Latn"},
    {"luy", "Latn"},
    {"lv", "Latn"},
    {"lwl", "Thai"},
    {"mad", "Latn"},
    {"mag", "Deva"},
    {"mai", "Deva"},
    {"mak", "Latn"},
    {"mak", "Bugi"},
    {"man", "Latn", "Nkoo"},
    {"mas", "Latn"},
    {"mdf", "Cyrl"},
    {"mdh", "Latn"},
    {"mdr", "Latn"},
    {"mdr", "Bugi"},
    {"men", "Latn"},
    {"mer", "Latn"},
    {"mfe", "Latn"},
    {"mg", "Latn"},
    {"mgh", "Latn"},
    {"mh", "Latn"},
    {"mi", "Latn"},
    {"mic", "Latn"},
    {"min", "Latn"},
    {"mk", "Cyrl"},
    {"ml", "Mlym"},
    {"mn", "Cyrl", "Mong"},
    {"mn", "Phag"},
    {"mnc", "Mong"},
    {"mni", "Beng"},
    {"mni", "Mtei"},
    {"mnk", "Latn"},
    {"mns", "Cyrl"},
    {"mnw", "Mymr"},
    {"moh", "Latn"},
    {"mos", "Latn"},
    {"mr", "Deva"},
    {"ms", "Latn"},
    {"ms", "Arab"},
    {"mt", "Latn"},
    {"mua", "Latn"},
    {"mus", "Latn"},
    {"mwl", "Latn"},
    {"mwr", "Deva"},
    {"my", "Mymr"},
    {"myv", "Cyrl"},
    {"myz", "Mand"},
    {"na", "Latn"},
    {"nap", "Latn"},
    {"naq", "Latn"},
    {"nb", "Latn"},
    {"nd", "Latn"},
    {"nds", "Latn"},
    {"ne", "Deva"},
    {"new", "Deva"},
    {"ng", "Latn"},
    {"nia", "Latn"},
    {"niu", "Latn"},
    {"nl", "Latn"},
    {"nmg", "Latn"},
    {"nn", "Latn"},
    {"nod", "Lana"},
    {"nog", "Cyrl"},
    {"nqo", "Nkoo"},
    {"nr", "Latn"},
    {"nso", "Latn"},
    {"nus", "Latn"},
    {"nv", "Latn"},
    {"ny", "Latn"},
    {"nym", "Latn"},
    {"nyn", "Latn"},
    {"nyo", "Latn"},
    {"nzi", "Latn"},
    {"oc", "Latn"},
    {"oj", "Cans"},
    {"oj", "Latn"},
    {"om", "Latn"},
    {"om", "Ethi"},
    {"or", "Orya"},
    {"os", "Cyrl", "Latn"},
    {"osa", "Latn"},
    {"osc", "Ital", "Latn"},
    {"otk", "Orkh"},
    {"pa", "Guru"},
    {"pa", "Arab"},
    {"pag", "Latn"},
    {"pal", "Phli"},
    {"pam", "Latn"},
    {"pap", "Latn"},
    {"pau", "Latn"},
    {"peo", "Xpeo"},
    {"phn", "Phnx"},
    {"pi", "Deva", "Sinh", "Thai"},
    {"pl", "Latn"},
    {"pon", "Latn"},
    {"pra", "Brah", "Khar"},
    {"prd", "Arab"},
    {"prg", "Latn"},
    {"prs", "Arab"},
    {"ps", "Arab"},
    {"pt", "Latn"},
    {"qu", "Latn"},
    {"raj", "Latn"},
    {"rap", "Latn"},
    {"rar", "Latn"},
    {"rcf", "Latn"},
    {"rej", "Latn"},
    {"rej", "Rjng"},
    {"rjs", "Deva"},
    {"rkt", "Beng"},
    {"rm", "Latn"},
    {"rn", "Latn"},
    {"ro", "Latn"},
    {"ro", "Cyrl"},
    {"rof", "Latn"},
    {"rom", "Cyrl", "Latn"},
    {"ru", "Cyrl"},
    {"rup", "Latn"},
    {"rw", "Latn"},
    {"rwk", "Latn"},
    {"sa", "Deva", "Sinh"},
    {"sad", "Latn"},
    {"saf", "Latn"},
    {"sah", "Cyrl"},
    {"sam", "Hebr", "Samr"},
    {"saq", "Latn"},
    {"sas", "Latn"},
    {"sat", "Latn"},
    {"sat", "Beng", "Deva", "Olck", "Orya"},
    {"saz", "Saur"},
    {"sbp", "Latn"},
    {"sc", "Latn"},
    {"scn", "Latn"},
    {"sco", "Latn"},
    {"sd", "Arab", "Deva"},
    {"sdh", "Arab"},
    {"se", "Latn"},
    {"se", "Cyrl"},
    {"see", "Latn"},
    {"seh", "Latn"},
    {"sel", "Cyrl"},
    {"ses", "Latn"},
    {"sg", "Latn"},
    {"sga", "Latn", "Ogam"},
    {"shi", "Arab"},
    {"shi", "Tfng"},
    {"shn", "Mymr"},
    {"si", "Sinh"},
    {"sid", "Latn"},
    {"sk", "Latn"},
    {"sl", "Latn"},
    {"sm", "Latn"},
    {"sma", "Latn"},
    {"smi", "Latn"},
    {"smj", "Latn"},
    {"smn", "Latn"},
    {"sms", "Latn"},
    {"sn", "Latn"},
    {"snk", "Latn"},
    {"so", "Latn"},
    {"so", "Arab", "Osma"},
    {"son", "Latn"},
    {"sq", "Latn"},
    {"sr", "Cyrl", "Latn"},
    {"srn", "Latn"},
    {"srr", "Latn"},
    {"ss", "Latn"},
    {"ssy", "Latn"},
    {"st", "Latn"},
    {"su", "Latn"},
    {"su", "Sund"},
    {"suk", "Latn"},
    {"sus", "Latn"},
    {"sus", "Arab"},
    {"sv", "Latn"},
    {"sw", "Latn"},
    {"swb", "Arab"},
    {"swb", "Latn"},
    {"swc", "Latn"},
    {"syl", "Beng"},
    {"syl", "Sylo"},
    {"syr", "Syrc"},
    {"ta", "Taml"},
    {"tab", "Cyrl"},
    {"tbw", "Latn"},
    {"tbw", "Tagb"},
    {"tcy", "Knda"},
    {"tdd", "Tale"},
    {"te", "Telu"},
    {"tem", "Latn"},
    {"teo", "Latn"},
    {"ter", "Latn"},
    {"tet", "Latn"},
    {"tg", "Arab", "Cyrl", "Latn"},
    {"th", "Thai"},
    {"ti", "Ethi"},
    {"tig", "Ethi"},
    {"tiv", "Latn"},
    {"tk", "Arab", "Cyrl", "Latn"},
    {"tkl", "Latn"},
    {"tli", "Latn"},
    {"tmh", "Latn"},
    {"tn", "Latn"},
    {"to", "Latn"},
    {"tog", "Latn"},
    {"tpi", "Latn"},
    {"tr", "Latn"},
    {"tr", "Arab"},
    {"tru", "Latn"},
    {"tru", "Syrc"},
    {"trv", "Latn"},
    {"ts", "Latn"},
    {"tsg", "Latn"},
    {"tsi", "Latn"},
    {"tt", "Cyrl"},
    {"tts", "Thai"},
    {"tum", "Latn"},
    {"tut", "Cyrl"},
    {"tvl", "Latn"},
    {"twq", "Latn"},
    {"ty", "Latn"},
    {"tyv", "Cyrl"},
    {"tzm", "Latn", "Tfng"},
    {"ude", "Cyrl"},
    {"udm", "Cyrl"},
    {"udm", "Latn"},
    {"ug", "Arab"},
    {"ug", "Cyrl", "Latn"},
    {"uga", "Ugar"},
    {"uk", "Cyrl"},
    {"uli", "Latn"},
    {"umb", "Latn"},
    {"unr", "Beng", "Deva"},
    {"unx", "Beng", "Deva"},
    {"ur", "Arab"},
    {"uz", "Arab", "Cyrl", "Latn"},
    {"vai", "Vaii"},
    {"ve", "Latn"},
    {"vi", "Latn"},
    {"vi", "Hani"},
    {"vo", "Latn"},
    {"vot", "Latn"},
    {"vun", "Latn"},
    {"wa", "Latn"},
    {"wae", "Latn"},
    {"wak", "Latn"},
    {"wal", "Ethi"},
    {"war", "Latn"},
    {"was", "Latn"},
    {"wo", "Latn"},
    {"wo", "Arab"},
    {"xal", "Cyrl"},
    {"xcr", "Cari"},
    {"xh", "Latn"},
    {"xog", "Latn"},
    {"xpr", "Prti"},
    {"xsa", "Sarb"},
    {"xsr", "Deva"},
    {"xum", "Ital", "Latn"},
    {"yao", "Latn"},
    {"yap", "Latn"},
    {"yav", "Latn"},
    {"yi", "Hebr"},
    {"yo", "Latn"},
    {"yrk", "Cyrl"},
    {"yue", "Hans"},
    {"za", "Latn"},
    {"za", "Hans"},
    {"zap", "Latn"},
    {"zen", "Tfng"},
    {"zh", "Hans", "Hant"},
    {"zh", "Bopo", "Phag"},
    {"zu", "Latn"},
    {"zun", "Latn"},
    {"zza", "Arab"},
  };

  private static final Map<String, ScriptTag> fontSpecificScript = new HashMap<>();
  private final Map<ScriptTag, Set<String>> scriptLangMap = new EnumMap<>(ScriptTag.class);

  static {
    fontSpecificScript.put("laoo", ScriptTag.lao);
    fontSpecificScript.put("yiii", ScriptTag.yi);
    fontSpecificScript.put("jpan", ScriptTag.kana);
    fontSpecificScript.put("kore", ScriptTag.hang);
    fontSpecificScript.put("nkoo", ScriptTag.nko);
    fontSpecificScript.put("vaii", ScriptTag.vai);
    fontSpecificScript.put("hans", ScriptTag.hani);
    fontSpecificScript.put("hant", ScriptTag.hani);
  }

  FontLanguages(List<String> availableLangs) {
    for (String[] entry : langScriptData) {
      String lang = entry[0];
      if (!availableLangs.contains(lang)) {
        continue;
      }
      for (int i = 1; i < entry.length; i++) {
        String script = entry[i].toLowerCase();
        ScriptTag scriptTag =
            fontSpecificScript.containsKey(script)
                ? fontSpecificScript.get(script)
                : ScriptTag.valueOf(script);
        addLangScriptMap(lang, scriptTag);
      }
    }

    scriptLangMap.put(ScriptTag.DFLT, new HashSet<>());
    scriptLangMap.put(ScriptTag.brai, new HashSet<>());
    scriptLangMap.put(ScriptTag.math, new HashSet<>());
    scriptLangMap.put(ScriptTag.musc, new HashSet<>());
    scriptLangMap.put(ScriptTag.musi, new HashSet<>());
    scriptLangMap.put(ScriptTag.mly2, scriptLangMap.get(ScriptTag.mlym));
    scriptLangMap.put(ScriptTag.mlm2, scriptLangMap.get(ScriptTag.mlym));
    scriptLangMap.put(ScriptTag.dev2, scriptLangMap.get(ScriptTag.deva));
    scriptLangMap.put(ScriptTag.mym2, scriptLangMap.get(ScriptTag.mymr));
    scriptLangMap.put(ScriptTag.tml2, scriptLangMap.get(ScriptTag.taml));
    scriptLangMap.put(ScriptTag.tel2, scriptLangMap.get(ScriptTag.telu));
    scriptLangMap.put(ScriptTag.knd2, scriptLangMap.get(ScriptTag.knda));
    scriptLangMap.put(ScriptTag.gur2, scriptLangMap.get(ScriptTag.guru));
    scriptLangMap.put(ScriptTag.gjr2, scriptLangMap.get(ScriptTag.gujr));
    scriptLangMap.put(ScriptTag.bng2, scriptLangMap.get(ScriptTag.beng));
    scriptLangMap.put(ScriptTag.ory2, scriptLangMap.get(ScriptTag.orya));
    scriptLangMap.put(ScriptTag.jamo, scriptLangMap.get(ScriptTag.hang));
  }

  private void addLangScriptMap(String lang, ScriptTag scriptTag) {
    if (!scriptLangMap.containsKey(scriptTag)) {
      scriptLangMap.put(scriptTag, new HashSet<>());
    }
    Set<String> langs = scriptLangMap.get(scriptTag);
    langs.add(lang);
  }

  Set<String> get(Font font) {
    Set<String> langs = new HashSet<>();
    GSubTable gsub = font.getTable(Tag.GSUB);
    if (gsub == null) {
      return langs;
    }

    ScriptListTable scriptList = gsub.scriptList();
    for (int i = 0; i < scriptList.count(); i++) {
      ScriptTag script = scriptList.scriptAt(i);
      if (scriptLangMap.containsKey(script)) {
        langs.addAll(scriptLangMap.get(script));
      } else {
        System.err.println("No language exists for the script: " + script);
      }
    }
    return langs;
  }
}
